package com.zgg.config;

import com.alibaba.druid.pool.DruidDataSourceFactory;
import com.zgg.config.datasource.AbstractDataSources;
import com.zgg.config.datasource.DynamicDataSource;
import com.zgg.enums.DataSourceEnum;
import org.apache.ibatis.session.SqlSessionFactory;
import org.mybatis.spring.SqlSessionFactoryBean;
import org.mybatis.spring.annotation.MapperScan;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.core.env.Environment;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;

import javax.sql.DataSource;
import java.lang.annotation.Annotation;
import java.util.HashMap;
import java.util.Map;
import java.util.Properties;
import java.util.Set;

/**
 * 根据jdbd.properties配置文件配置多个数据源
 * <p>
 * <p>
 * Created by li on 2017/4/7.
 */
@Configuration
@MapperScan(basePackages = {"com.zgg.files.dao"})
public class DataSourcesConfig extends AbstractDataSources {

    private Logger logger = LoggerFactory.getLogger(DataSourcesConfig.class);

    @Autowired
    private Environment env;

    /**
     * 创建多数据源
     *
     * @return
     * @throws Exception
     */
    @Bean
    @Primary
    public DynamicDataSource createDataSource() throws Exception {

        /**
         * targetDataSources属性。
         * 最后需要将targetDataSources给设置到DynamicDataSource里。
         */
        Map<String, DataSource> targetDataSources = new HashMap<>();
        //创建动态数据源对象DynamicDataSource
        DynamicDataSource dataSource = new DynamicDataSource();
        /**
         * 读取本地配置文件，将本地配置加载到druid中。
         */
        Map<String, Properties> propertiesMap = getResource(env.getProperty("datasource_file.file_path"));//;getXAResource()
        Set<String> keySet = propertiesMap.keySet();
        /**
         * 根据数据源的名称，获取对应的属性，并创建DruidDataSource对象。
         * 将DruidDataSource对象添加到targetDataSources属性中。
         * 设置主数据源。
         */
        for (String key : keySet) {
            DataSource druidDataSource = DruidDataSourceFactory.createDataSource(propertiesMap.get(key));
            targetDataSources.put(propertiesMap.get(key).getProperty(DataSourceEnum.DATABASE_NAME.getValue()), druidDataSource);
        }
        /**
         * 当数据源个数大于等于一个时，取第一个数据源做为默认的数据源
         */
        if (targetDataSources.size() > 0) {
            dataSource.setDefaultTargetDataSource(targetDataSources.get(keySet.toArray()[0]));
        }

        //ShardingRuleConfiguration shardingRuleConfig = new ShardingRuleConfiguration();
        //
        //shardingRuleConfig.getTableRuleConfigs().add(getTableRuleConfiguration(keySet));
        //shardingRuleConfig.getBindingTableGroups().add("oss_files");
        ////shardingRuleConfig.setDefaultTableShardingStrategyConfig();
        //ShardingRule shardingRule = new ShardingRule(shardingRuleConfig, keySet);
        //
        //
        //ShardingDataSource shardingDataSource = new ShardingDataSource(targetDataSources, shardingRule);
        /**
         * 从注册中心获取其它注册的数据库配置信息，并将其添加到本地DataSource中。
         */
//        targetDataSources = createTargetDataSourcesMap();

        dataSource.setTargetDataSources(targetDataSources);
        return dataSource;
    }

    //@Bean
    //public TableRuleConfiguration getTableRuleConfiguration(Set<String> dbNames) {
    //    TableRuleConfiguration tableRuleConfiguration = new TableRuleConfiguration();
    //    if (dbNames != null && dbNames.size() > 0) {
    //        for (String dbName : dbNames) {
    //            tableRuleConfiguration.setLogicTable("oss_files");
    //            /**
    //             * 分库分表：user_${0..1}.user_info_${0..1}
    //             * user_:库
    //             * user_info_：表
    //             */
    //            tableRuleConfiguration.setActualDataNodes(dbName + ".oss_files${2018..2100}");
    //            tableRuleConfiguration.setKeyGeneratorColumnName("id");
    //            tableRuleConfiguration.setTableShardingStrategyConfig(new HintShardingStrategyConfiguration(new MyHintShardingAlgorithm()));
    //        }
    //    }
    //
    //    return tableRuleConfiguration;
    //}

    @Bean
    public SqlSessionFactory sqlSessionFactory(DynamicDataSource ds) throws Exception {
        SqlSessionFactoryBean fb = new SqlSessionFactoryBean();
        fb.setDataSource(ds);// 指定数据源(这个必须有，否则报错)
        // 下边两句仅仅用于*.xml文件，如果整个持久层操作不需要使用到xml文件的话（只用注解就可以搞定），则不加

//        // 分页插件
//        PageHelper pageHelper = new PageHelper();
//        Properties props = new Properties();
//        props.setProperty("reasonable", env.getProperty("pagehelper.reasonable"));//String.valueOf(reasonable));
//        props.setProperty("supportMethodsArguments", env.getProperty("pagehelper.support-methods-arguments"));// String.valueOf(supportMethodsArguments));
//        props.setProperty("returnPageInfo", env.getProperty("pagehelper.return-pageInfo"));// returnPageInfo);
//        props.setProperty("params", env.getProperty("pagehelper.params"));//        params);
//        props.setProperty("offsetAsPageNum", env.getProperty("pagehelper.offset-as-page-num"));// String.valueOf(offsetAsPageNum));
//        props.setProperty("rowBoundsWithCount", env.getProperty("pagehelper.row-bounds-with-count"));//String.valueOf(rowBoundsWithCount));
//        props.setProperty("pageSizeZero", env.getProperty("pagehelper.page-size-zero"));//String.valueOf(pageSizeZero));
//        props.setProperty("dialect", env.getProperty("pagehelper.dialect"));// dialect);
//
//        pageHelper.setProperties(props);

        fb.setTypeAliasesPackage(env.getProperty("mybatis.type-aliases-package"));// 指定基包
//        fb.setPlugins(new Interceptor[]{(Interceptor) pageHelper});

        fb.setMapperLocations(new PathMatchingResourcePatternResolver().getResources(env.getProperty("mybatis.mapperLocations")));
        return fb.getObject();
    }

    @Bean
    public DataSourceTransactionManager transactionManager(DynamicDataSource dataSource) throws Exception {
        /**
         * 查看当前数据源信息
         * ((DynamicDataSource)((DataSourceTransactionManager)SpringUtil.getBean("transactionManager")).getDataSource()).defaultTargetDataSource
         */
        return new DataSourceTransactionManager(dataSource);
    }

    @Override
    public String value() {
        return null;
    }

    @Override
    public Class<? extends Annotation> annotationType() {
        return null;
    }
}
